#include <printk.h>
#include <intr/exception.h>
#include <intr/isr.h>
#include <intr/idt.h>

void do_divide_error_isr(intr_arg_t *arg)
{
    printk("Division Error, code=%lx\n", arg->errcode);
}
void do_debug_isr(intr_arg_t *arg)
{
    printk("Debug, code=%lx\n", arg->errcode);
}
void do_nmi_isr(intr_arg_t *arg)
{
    printk("NMI, code=%lx\n", arg->errcode);
}
void do_int3_isr(intr_arg_t *arg)
{
    printk("Breakpoint, code=%lx\n", arg->errcode);
}
void do_into_isr(intr_arg_t *arg)
{
    printk("Overflow, code=%lx\n", arg->errcode);
}
void do_bound_isr(intr_arg_t *arg)
{
    printk("Bound Range Exceeded, code=%lx\n", arg->errcode);
}
void do_ud2_isr(intr_arg_t *arg)
{
    printk("Invalid Opcode, code=%lx\n", arg->errcode);
}
void do_fwait_isr(intr_arg_t *arg)
{
    printk("Device Not Available, code=%lx\n", arg->errcode);
}
void do_double_fault_isr(intr_arg_t *arg)
{
    printk("Double Fault, code=%lx,func=%lx,rip=%lx\n", arg->errcode, arg->func, arg->rip);
    while (1)
        ;
}
void do_coprocessor_segment_cross_isr(intr_arg_t *arg)
{
    printk("Coprocessor Segment Overrun, code=%lx\n", arg->errcode);
}
void do_invalid_tss_isr(intr_arg_t *arg)
{
    printk("Invalid TSS, code=%lx\n", arg->errcode);
}
void do_segment_not_exist_isr(intr_arg_t *arg)
{
    printk("Segment Not Present, code=%lx\n", arg->errcode);
}
void do_stack_segment_fault_isr(intr_arg_t *arg)
{
    printk("Stack-Segment Fault, code=%lx\n", arg->errcode);
}
void do_general_isr(intr_arg_t *arg)
{
    printk("General Protection Fault, code=%lx\n", arg->errcode);
}
void do_page_fault_isr(intr_arg_t *arg)
{
    printk("Page Fault, code=%lx\n", arg->errcode);
}
void do_fpe_isr(intr_arg_t *arg)
{
    printk("x87 Floating-Point Exception, code=%lx\n", arg->errcode);
}
void do_align_check_isr(intr_arg_t *arg)
{
    printk("Alignment Check, code=%lx\n", arg->errcode);
}
void do_machine_check_isr(intr_arg_t *arg)
{
    printk("Machine Check, code=%lx\n", arg->errcode);
    while (1)
        ;
}
void do_simd_fpe_isr(intr_arg_t *arg)
{
    printk("SIMD Floating-Point Exception, code=%lx\n", arg->errcode);
}
void do_virtual_isr(intr_arg_t *arg)
{
    printk("Virtualization Exception, code=%lx\n", arg->errcode);
}
void do_control_protection_exception_isr(intr_arg_t *arg)
{
    printk("Control Protection Exception, code=%lx\n", arg->errcode);
}
void do_hypervisor_injection_excetion_isr(intr_arg_t *arg)
{
    printk("Hypervisor Injection Exception, code=%lx\n", arg->errcode);
}
void do_vmm_communication_exception_isr(intr_arg_t *arg)
{
    printk("VMM Communication Exception, code=%lx\n", arg->errcode);
}
void do_security_exception_isr(intr_arg_t *arg)
{
    printk("Security Exception, code=%lx\n", arg->errcode);
}
void do_unkonw_intr_isr(intr_arg_t *arg)
{
    printk("Unkown intrrupt, code=%lx\n", arg->errcode);
}


void init_exception() {
    //Exceptions
    set_trap_gate(0, 1, divide_error_isr);
    set_trap_gate(1, 1, debug_isr);
    set_intr_gate(2, 1, nmi_isr);
    set_sys_trap_gate(3, 1, int3_isr);
    set_sys_trap_gate(4, 1, into_isr);
    set_sys_trap_gate(5, 1, bound_isr);
    set_trap_gate(6, 1, ud2_isr);
    set_trap_gate(7, 1, fwait_isr);
    set_trap_gate(8, 1, double_fault_isr);
    set_trap_gate(9, 1, coprocessor_segment_cross_isr);
    set_trap_gate(10, 1, invalid_tss_isr);
    set_trap_gate(11, 1, segment_not_exist_isr);
    set_trap_gate(12, 1, stack_segment_fault_isr);
    set_trap_gate(13, 1, general_isr);
    set_trap_gate(14, 1, page_fault_isr);
    // 15 reserved
    set_trap_gate(16, 1, fpe_isr);
    set_trap_gate(17, 1, align_check_isr);
    set_trap_gate(18, 1, machine_check_isr);
    set_trap_gate(19, 1, simd_fpe_isr);
    set_trap_gate(20, 1, virtual_isr);
    set_trap_gate(21, 1, control_protection_exception_isr);
    // 22-27 reserved
    set_trap_gate(28, 1, hypervisor_injection_excetion_isr);
    set_trap_gate(29, 1, vmm_communication_exception_isr);
    set_trap_gate(30, 1, security_exception_isr);
    // 31 reserved

    printk("exception init complete\n");
}